package com.songlanyun.modules.signin.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import com.songlanyun.common.enums.LoveConstant;
import com.songlanyun.modules.account.entity.UserIdentityAssetEntity;
import com.songlanyun.modules.loverecord.service.UserLoveRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;
import com.songlanyun.modules.account.service.UserIdentityAssetService;
import com.songlanyun.modules.coupon.entity.CouponEntity;
import com.songlanyun.modules.coupon.service.CouponReceiveRecordService;
import com.songlanyun.modules.coupon.service.CouponService;
import com.songlanyun.modules.signin.dao.SignInRecordDao;
import com.songlanyun.modules.signin.entity.SignInConfigEntity;
import com.songlanyun.modules.signin.entity.SignInRecordEntity;
import com.songlanyun.modules.signin.model.dto.SignInRecordPageReq;
import com.songlanyun.modules.signin.model.vo.SignInDataStatisticsVo;
import com.songlanyun.modules.signin.model.vo.SignInRecordVo;
import com.songlanyun.modules.signin.service.SignInConfigService;
import com.songlanyun.modules.signin.service.SignInRecordService;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

/**
 * 签到管理-签到配置
 *
 * @author lijiahe
 * @date 2022-08-03
 */
@Service("signInRecordService")
public class SignInRecordServiceImpl extends ServiceImpl<SignInRecordDao, SignInRecordEntity>
        implements SignInRecordService {

    @Autowired
    private SignInConfigService signInConfigService;

    @Autowired
    private CouponReceiveRecordService couponReceiveRecordService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private UserLoveRecordService userLoveRecordService;

    @Autowired
    private UserIdentityAssetService userIdentityAssetService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SignInRecordVo> page =
                baseMapper.querySignInRecordPage(new Query<SignInRecordVo>().getPage(params), paramsMapToReq(params));
        return new PageUtils(page);
    }

    private SignInRecordPageReq paramsMapToReq(Map<String, Object> params) {
        SignInRecordPageReq req = new SignInRecordPageReq();
        String startTime = MapUtil.getStr(params, "startTime");
        if (StrUtil.isNotBlank(startTime)) {
            req.setStartTime(startTime);
        }
        String endTime = MapUtil.getStr(params, "endTime");
        if (StrUtil.isNotBlank(endTime)) {
            req.setEndTime(endTime);
        }
        String mobile = MapUtil.getStr(params, "mobile");
        if (StrUtil.isNotBlank(mobile)) {
            req.setMobile(mobile);
        }
        Integer isWithBonus = MapUtil.getInt(params, "isWithBonus");
        if (ObjectUtils.isNotNull(isWithBonus)) {
            req.setIsWithBonus(isWithBonus);
        }
        return req;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String signInNow(Long userId, LocalDateTime dayTime) {
        String day = dayTime.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Integer integer = baseMapper.selectCount(new LambdaQueryWrapper<SignInRecordEntity>()
                .eq(SignInRecordEntity::getUserId, userId).like(SignInRecordEntity::getSignInTime, day));
        if (NumberUtil.isGreater(NumberUtil.toBigDecimal(integer), BigDecimal.ZERO)) {
            throw new RRException("当日已签到");
        }

        SignInConfigEntity signInConfigEntity = signInConfigService.get(false);
        if (ObjectUtil.isNull(signInConfigEntity)) {
            signInConfigEntity = new SignInConfigEntity();
        }
        Integer loveValue = signInConfigEntity.getLoveValue();
        Integer monthSignIn = signInConfigEntity.getMonthSignIn();
        String rewardCoupons = signInConfigEntity.getRewardCoupons();
        Integer numberRewards = signInConfigEntity.getNumberRewards();

        SignInRecordEntity entity = new SignInRecordEntity();
        entity.setUserId(userId);
        entity.setSignInTime(dayTime);
        entity.setIntegral(loveValue);
        baseMapper.insert(entity);

        //保存爱心收支记录及更新会员爱心值
        userLoveRecordService.add(userId, true, loveValue, LoveConstant.ModelType.DAILY_ATTENDANCE, entity.getId(), "每日签到");

        String month = dayTime.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        // 当月已签到次数
        Integer singInNum = baseMapper.selectSignInNum(userId, month, null);

        if (NumberUtil.equals(NumberUtil.toBigDecimal(monthSignIn), BigDecimal.ZERO)) {
            // 当月度签到为0时,则需要满签才能发放优惠券
            int monthValue = dayTime.getMonthValue();
            if (NumberUtil.equals(singInNum, monthValue)) {
                this.issueCoupons(entity, userId, month, rewardCoupons, numberRewards);
            }
        } else {
            if (NumberUtil.equals(monthSignIn, singInNum)) {
                this.issueCoupons(entity, userId, month, rewardCoupons, numberRewards);
            }
        }

        return String.format("本月已签到%d天，爱心值+%d", singInNum, loveValue);
    }

    @Override
    public SignInDataStatisticsVo dataStatistics(Long userId, String month) {

        SignInDataStatisticsVo signInDataStatisticsVo = new SignInDataStatisticsVo();
        Integer numDaySignInThisMonth = baseMapper.selectSignInNum(userId, month, null);
        Integer cumulativeSignIn = baseMapper.selectSignInNum(userId, null, null);
        Integer cumulativeLoveValue = baseMapper.selectCumulativeLoveValue(userId, null);

        signInDataStatisticsVo.setNumDaySignInThisMonth(numDaySignInThisMonth);
        signInDataStatisticsVo.setCumulativeSignIn(cumulativeSignIn);
        signInDataStatisticsVo.setCumulativeLoveValue(cumulativeLoveValue);

        //注意事项
        SignInConfigEntity signInConfigEntity = signInConfigService.get(false);
        if (ObjectUtil.isNotNull(signInDataStatisticsVo)) {
            signInDataStatisticsVo.setRules(signInConfigEntity.getRules());
        }
//        CouponEntity couponEntity = couponService.loadByCode(signInConfigEntity.getRewardCoupons(), false);
//        if (ObjectUtil.isNotNull(signInConfigEntity) && ObjectUtil.isNotNull(couponEntity) && !NumberUtil.equals(signInConfigEntity.getNumberRewards(), 0)) {
//            Integer monthSignIn = signInConfigEntity.getMonthSignIn();
//            StringBuilder builder = new StringBuilder("注意：每月签到");
//            String monthSignInContent;
//            if (NumberUtil.equals(monthSignIn, 0)) {
//                monthSignInContent = "满勤";
//            } else {
//                monthSignInContent = monthSignIn + "天";
//            }
//            builder.append(monthSignInContent).append("，可以获取").append("“").append(couponEntity.getName()).append("”").append("优惠券");
//            if (signInConfigEntity.getNumberRewards() > 1) {
//                builder.append(signInConfigEntity.getNumberRewards()).append("张");
//            }
//            builder.append("，签到").append(monthSignInContent).append("后自动到账，到“优惠券”中查看");
//            signInDataStatisticsVo.setRules(builder.toString());
//        }

        return signInDataStatisticsVo;
    }

    @Override
    public List<String> listSignInRecord(Long userId, String month) {
        return baseMapper.selectListSignInRecord(userId, month);
    }

    /**
     * 发放优惠券
     */
    private void issueCoupons(SignInRecordEntity entity, Long userId, String month, String rewardCoupons,
                              Integer numberRewards) {
        Integer singInCouponNum = baseMapper.selectSignInNum(userId, month, BigDecimal.ZERO.intValue());
        // 当前月份已发放过优惠券则不在发放
        if (NumberUtil.equals(NumberUtil.toBigDecimal(singInCouponNum), BigDecimal.ZERO)) {
            if (NumberUtil.isGreater(NumberUtil.toBigDecimal(numberRewards), BigDecimal.ZERO)) {
                CouponEntity couponEntity = couponService.loadByCode(rewardCoupons, false);
                if (ObjectUtil.isNotNull(entity)) {
                    entity.setCouponId(couponEntity.getId());
                    entity.setCouponName(couponEntity.getName());
                    entity.setNumberRewards(numberRewards);
                    baseMapper.updateById(entity);
                }

                for (int i = 0; i < numberRewards; i++) {
                    // 发放优惠券
                    couponReceiveRecordService.give(userId, rewardCoupons, false);
                }
            }
        }
    }
}
